/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package Scenery.Map;

import Scenery.BaseBuilder;
import Scenery.Thing.HardCodeSignTexts;
import Scenery.Thing.Thing;
import Scenery.Thing.Things.Crate;
import Scenery.Thing.Things.Plank;
import Scenery.Thing.Things.Sign;
import com.jme3.scene.Node;
import java.util.ArrayList;
import java.util.HashMap;
import jme3tools.optimize.GeometryBatchFactory;
import main.Memory.Memory;

/*
 * 
 * @author: Ziden
 * 
 */

public class Map {

    int fat = 0;
    int tall = 0;
    Tile[][] map;
    private Node staticMapModel;
    private Node objects;
    private Node mapRootNode;
    private Node entityNode = new Node("enode");
    
    public Map(int fat, int tall) {
        staticMapModel = new Node();
        objects = new Node("mapObjects");
        mapRootNode = new Node("mapRoot");
        objects.attachChild(entityNode);
        this.fat = fat;
        this.tall = tall;
        this.map = new Tile[fat][tall];
    }

    public void buildMapModel() {
        for (int x = 0; x < fat; x++) {
            for (int y = 0; y < tall; y++) {
                buildTile(x, y);
            }
        }
        // this will be removed when mapeditor comes in
        HardCodeSignTexts.writeSigns();
        //GeometryBatchFactory.optimize(staticMapModel);
        mapRootNode.attachChild(objects);
        mapRootNode.attachChild(staticMapModel);
    }

    public void buildTile(int x, int y) {

        // TILES
        switch (map[x][y].getId()) {
            case TypeDefs.STONE_FLOOR:
                staticMapModel.attachChild(BaseBuilder.makeBaseBlock(x * 2, 0, y * 2));
                checkBuildWall(x, y);
                break;
            case TypeDefs.corridor:
                staticMapModel.attachChild(BaseBuilder.makeBaseBlock(x * 2, 0, y * 2));
                checkBuildWall(x, y);
                break;
            case TypeDefs.door:
                staticMapModel.attachChild(BaseBuilder.makeBaseBlock(x * 2, 0, y * 2));
                checkBuildWall(x, y);
                break;
            case TypeDefs.roomWall:
                staticMapModel.attachChild(BaseBuilder.makeBaseStone(x * 2, 0, y * 2));
                checkBuildWall(x, y);
                break;
            case TypeDefs.WALL:
                staticMapModel.attachChild(BaseBuilder.makeBaseStone(x * 2, 0, y * 2));
                checkBuildWall(x, y);
                break;
            case TypeDefs.grass:
                staticMapModel.attachChild(BaseBuilder.makeBaseTile(x, 0, y,"grass"));
                checkBuildWall(x, y);
                break;
            case TypeDefs.AIR:
                // if i have a floor nearby, i become a wall
                checkBuildWall(x, y);
                break;
        }
    }

    public void checkBuildWall(int x, int y) {
        if (map[x][y].getId() == TypeDefs.AIR) {
            if (x < fat - 1) {
                if (map[x + 1][y].getId() == TypeDefs.STONE_FLOOR || map[x + 1][y].getId() == TypeDefs.corridor || map[x + 1][y].getId() == TypeDefs.door) {
                    map[x][y].setId(TypeDefs.WALL);
                    staticMapModel.attachChild(BaseBuilder.makeBaseStone(x * 2, 0, y * 2));
                }
            }
            if (x > 0) {
                if (map[x - 1][y].getId() == TypeDefs.STONE_FLOOR || map[x - 1][y].getId() == TypeDefs.corridor || map[x - 1][y].getId() == TypeDefs.door) {
                    map[x][y].setId(TypeDefs.WALL);
                    staticMapModel.attachChild(BaseBuilder.makeBaseStone(x * 2, 0, y * 2));
                }
            }
            if (y < tall - 1) {
                if (map[x][y + 1].getId() == TypeDefs.STONE_FLOOR || map[x][y + 1].getId() == TypeDefs.door || map[x][y + 1].getId() == TypeDefs.corridor) {
                    map[x][y].setId(TypeDefs.WALL);
                    staticMapModel.attachChild(BaseBuilder.makeBaseStone(x * 2, 0, y * 2));
                }
            }
            if (y > 0) {
                if (map[x][y - 1].getId() == TypeDefs.STONE_FLOOR || map[x][y - 1].getId() == TypeDefs.corridor || map[x][y - 1].getId() == TypeDefs.door) {
                    map[x][y].setId(TypeDefs.WALL);
                    staticMapModel.attachChild(BaseBuilder.makeBaseStone(x * 2, 0, y * 2));
                }
            }
        } else  if (map[x][y].getId() == TypeDefs.STONE_FLOOR) { 
            if(x==fat-1) {
                staticMapModel.attachChild(BaseBuilder.makeBaseStone(fat * 2, 0, y * 2));
            } if(x==0) {
                staticMapModel.attachChild(BaseBuilder.makeBaseStone(-2, 0, y * 2));
            } if(y==tall-1) {
                staticMapModel.attachChild(BaseBuilder.makeBaseStone(x * 2, 0, tall * 2));
            } if(y==0) {
                staticMapModel.attachChild(BaseBuilder.makeBaseStone(x * 2, 0, -2));
            }
            
        }
    }
    
    public void addObjectNode(Node objNode) {
        entityNode.attachChild(objNode);
    }

    public int getFat() {
        return fat;
    }

    public void setFat(int fat) {
        this.fat = fat;
    }

    public Tile[][] getMap() {
        return map;
    }

    public void setMap(Tile[][] map) {
        this.map = map;
    }

    public Node getStaticMap() {
        return staticMapModel;
    }

    public void setMapModel(Node mapModel) {
        this.staticMapModel = mapModel;
    }

    public int getTall() {
        return tall;
    }

    public void setTall(int tall) {
        this.tall = tall;
    }

    public Node getRootMapNode() {
        return this.mapRootNode;
    }

    public Node getEntityNode() {
        return entityNode;
    }

    public void setEntityNode(Node entityNode) {
        this.entityNode = entityNode;
    }

    public Node getMapRootNode() {
        return mapRootNode;
    }

    public void setMapRootNode(Node mapRootNode) {
        this.mapRootNode = mapRootNode;
    }

    public Node getObjects() {
        return objects;
    }

    public void setObjects(Node objects) {
        this.objects = objects;
    }

    public Node getStaticMapModel() {
        return staticMapModel;
    }

    public void setStaticMapModel(Node staticMapModel) {
        this.staticMapModel = staticMapModel;
    }
    
    
}
